home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr35 / jamapi.zip / JAMUTIL.ZIP / JAMUTIL.C next >
C/C++ Source or Header  |  1993-07-01  |  17KB  |  663 lines

  1. /*
  2. **  JAM(mbp) - The Joaquim-Andrew-Mats Message Base Proposal
  3. **
  4. **  JAM Utility
  5. **
  6. **  Written by Mats Wallin & Mats Birch
  7. **
  8. **  ----------------------------------------------------------------------
  9. **
  10. **  jamutil.c (JAMmb)
  11. **
  12. **  JAM Utility, display contents of a JAM messagebase
  13. **
  14. **  Copyright 1993 Joaquim Homrighausen, Andrew Milner, Mats Birch, and
  15. **  Mats Wallin. ALL RIGHTS RESERVED.
  16. **
  17. **  93-06-28    MW
  18. **  Initial coding
  19. */
  20.  
  21. #include <ctype.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <time.h>
  26.  
  27. #if defined(__MSDOS__)
  28. #include <fcntl.h>
  29. #include <io.h>
  30. #endif
  31.  
  32. #if defined(__sparc__)
  33. #include <fcntl.h>
  34. #include <unistd.h>
  35. #endif
  36.  
  37. #include "jammb.h"
  38.  
  39. #include "jamutil.h"
  40.  
  41.  
  42. /*
  43. **  Prototypes
  44. */
  45.  
  46. int InitJAMAPIREC( JAMAPIREC * pJam, CHAR8 * pFile );
  47. int DisplayMsgHdr( INT32 MsgNo );
  48. int DisplayMsgSubFld( void );
  49. int DisplayMsgTxt( void );
  50. int DisplayHdrInfo( void );
  51. CHAR8 * AttrToStr( UINT32 Attr );
  52. CHAR8 * GetSubFldName( JAMSUBFIELD * pSubFld );
  53. CHAR8 * GetSubFldStr( JAMSUBFIELD * pSubFld );
  54. CHAR8 * DispTime( UINT32 * pt );
  55.  
  56. #if !defined(__MSDOS__)
  57. UINT32 filelength( int fh );
  58. #endif
  59.  
  60.  
  61. /* ---------------------------------------------------------------------- *
  62.  *
  63.  *  main
  64.  *
  65.  * ---------------------------------------------------------------------- */
  66.  
  67. int main( int argc, CHAR8 * argv [] )
  68. {
  69.   CHAR8 JamFileName [128];
  70.   INT32 MsgNo;
  71.   int   ch,
  72.         done;
  73.  
  74.   puts( "JAMutil\n"
  75.         "Copyright 1993 Joaquim Homrighausen, Andrew Milner, Mats Birch, and\n"
  76.         "               Mats Wallin. ALL RIGHTS RESERVED\n"
  77.         "Written by Mats Wallin & Mats Birch\n" );
  78.  
  79.   if( argc < 2 || argc > 3 )
  80.     {
  81.     puts( "Format: JAMUTIL <JAMfile> [<MsgNo>]\n" 
  82.           "where: <JAMfile> is the path and base filename to the JAM messagebase\n"
  83.           "       <MsgNo>   is the first message number to display\n" );
  84.     return( 1 );
  85.     }
  86.  
  87.  
  88.   strcpy( JamFileName, argv [1] );
  89.   if( argc == 3 )
  90.     MsgNo = atol( argv [2] );
  91.   else
  92.     MsgNo = 0;
  93.  
  94.  
  95. /*
  96. **  Initiate the JAMAPIREC variable, and open the JAM messagebase
  97. */
  98.  
  99.   if( !JAMsysInitApiRec( &JamRec, JamFileName, WORKBUFSIZE ))
  100.     {
  101.     puts( "Out of memory" );
  102.     return( 1 );
  103.     }
  104.  
  105.   if( !JAMmbOpen( &JamRec ))
  106.     {
  107.     printf( "Unable to open messagebase: %s, code: %d, errno: %d\n", JamFileName, JamRec.APImsg, JamRec.Errno );
  108.     return( 1 );
  109.     }
  110.  
  111.  
  112. /*
  113. **  Display the specified (or first if none were specified) message in this
  114. **  messagebase
  115. */
  116.  
  117.   if( MsgNo == 0L )
  118.     MsgNo = JamRec.HdrInfo.BaseMsgNum;
  119.  
  120.   DisplayMsgHdr( MsgNo );
  121.  
  122.  
  123.  
  124. /*
  125. **  Display a prompt, and let the user choose what to do next
  126. */
  127.  
  128.   while( 1 )
  129.     {
  130.     printf( "\nQ=Quit  S=Subfields  T=Text  N=Next  P=Previous  H=HdrInfo   :" );
  131.  
  132.     do
  133.       {
  134.       ch = getchar();
  135.       ch = toupper( ch );
  136.       done = 1;
  137.  
  138.       switch( ch )
  139.         {
  140.         case  'Q' :
  141.         case  27 :
  142.           puts( "Quit\n" );
  143.           return( 0 );
  144.  
  145.         case 'H' :
  146.           puts( "HdrInfo\n" );
  147.           DisplayHdrInfo( );
  148.           break;
  149.  
  150.         case 'P' :
  151.           puts( "Prev\n" );
  152.           DisplayMsgHdr( --MsgNo );
  153.           break;
  154.  
  155.         case 'S' :
  156.           puts( "SubFld\n" );
  157.           DisplayMsgSubFld( );
  158.           break;
  159.       
  160.         case 'T' :
  161.           puts( "Text\n" );
  162.           DisplayMsgTxt( );
  163.           break;
  164.  
  165.         case 'N' :
  166.         case 13 :
  167.           puts( "Next\n" );
  168.           DisplayMsgHdr( ++MsgNo );
  169.           break;
  170.  
  171.         case '0' :
  172.         case '1' :
  173.         case '2' :
  174.         case '3' :
  175.         case '4' :
  176.         case '5' :
  177.         case '6' :
  178.         case '7' :
  179.         case '8' :
  180.         case '9' :
  181.           {
  182.           CHAR8   Buf [16];
  183.  
  184.           putchar( ch );
  185.           Buf [0] = ( CHAR8 ) ch;
  186.           fgets( Buf + 1, sizeof( Buf ) - 1, stdin );
  187.           putchar( '\n' );
  188.  
  189.           MsgNo = atol( Buf );
  190.           DisplayMsgHdr( MsgNo );
  191.           break;
  192.           }
  193.  
  194.         default :
  195.           done = 0;
  196.           break;
  197.         }
  198.       }
  199.     while( !done );
  200.     }
  201.  
  202.  
  203.   return( 0 );
  204. }
  205.  
  206.  
  207. /* ---------------------------------------------------------------------- *
  208.  *
  209.  *  DisplayMsgHdr
  210.  *
  211.  *    Displays all header information for the specified message.
  212.  *    The message header is first read from the messagebase
  213.  *
  214.  *    Parameters:   INT32 MsgNo   - The message to display
  215.  *
  216.  *    Returns:      0             - Failure
  217.  *                  1             - Success
  218.  *
  219.  * ---------------------------------------------------------------------- */
  220.  
  221. int DisplayMsgHdr( INT32 MsgNo )
  222. {
  223.   printf( "Message number: %lu\n\n", MsgNo );
  224.  
  225.  
  226. /*
  227. **  Check that the messagenumber where valid
  228. */
  229.  
  230.   if(( MsgNo - JamRec.HdrInfo.BaseMsgNum ) * sizeof( JAMIDXREC ) >= filelength( JamRec.IdxHandle ))
  231.     {
  232.     puts( "No more messages" );
  233.     return( 0 );
  234.     }
  235.  
  236.   if( MsgNo < JamRec.HdrInfo.BaseMsgNum )
  237.     {
  238.     printf( "Invalid message number: %ld\n", MsgNo );
  239.     return( 0 );
  240.     }
  241.  
  242.  
  243. /*
  244. **  Read the message header (but we don't want to read the subfields)
  245. */
  246.                               
  247.   if( !JAMmbFetchMsgHdr( &JamRec, MsgNo, 0 ))
  248.     {
  249.     printf( "Error reading message header, code: %d, errno: %d\n", JamRec.APImsg, JamRec.Errno );
  250.     return( 0 );
  251.     }
  252.  
  253.  
  254. /*
  255. **  Display the header contents
  256. */
  257.  
  258.   printf( "Signature    : <%02x><%02x><%02x><%02x>\n",
  259.                                     JamRec.Hdr.Signature [0],
  260.                                     JamRec.Hdr.Signature [1],
  261.                                     JamRec.Hdr.Signature [2],
  262.                                     JamRec.Hdr.Signature [3] );
  263.   printf( "Revision     : %04xh\n", JamRec.Hdr.Revision );
  264.   printf( "SubfieldLen  : %lu\n",   JamRec.Hdr.SubfieldLen );
  265.   printf( "TimesRead    : %lu\n",   JamRec.Hdr.TimesRead );
  266.   printf( "MsgIdCRC     : %08lx\n", JamRec.Hdr.MsgIdCRC );
  267.   printf( "ReplyCRC     : %08lx\n", JamRec.Hdr.ReplyCRC );
  268.   printf( "ReplyTo      : %lu\n",   JamRec.Hdr.ReplyTo );
  269.   printf( "Reply1st     : %lu\n",   JamRec.Hdr.Reply1st );
  270.   printf( "ReplyNext    : %lu\n",   JamRec.Hdr.ReplyNext );
  271.   printf( "DateWritten  : %s",      JamRec.Hdr.DateWritten ? DispTime( &JamRec.Hdr.DateWritten ) : "<null>\n" );
  272.   printf( "DateReceived : %s",      JamRec.Hdr.DateReceived ? DispTime( &JamRec.Hdr.DateReceived ) : "<null>\n" );
  273.   printf( "DateProcessed: %s",      JamRec.Hdr.DateProcessed ? DispTime( &JamRec.Hdr.DateProcessed ) : "<null>\n" );
  274.   printf( "MsgNum       : %lu\n",   JamRec.Hdr.MsgNum );
  275.   printf( "Attribute    : %s\n",    AttrToStr( JamRec.Hdr.Attribute ));
  276.   printf( "Attribute2   : %lu\n",   JamRec.Hdr.Attribute2 );
  277.   printf( "TxtOffset    : %lu\n",   JamRec.Hdr.TxtOffset );
  278.   printf( "TxtLen       : %lu\n",   JamRec.Hdr.TxtLen );
  279.   printf( "PasswordCRC  : %08lx\n", JamRec.Hdr.PasswordCRC );
  280.   printf( "Cost         : %u\n", JamRec.Hdr.Cost );
  281.  
  282.   return( 1 );
  283. }
  284.  
  285.  
  286. /* ---------------------------------------------------------------------- *
  287.  *
  288.  *  DisplayMsgSubFld
  289.  *
  290.  *    Displays all subfields in the message header of the current
  291.  *    message. The message header is first read once more, to make
  292.  *    sure that we have the subfields in the buffer. (The same buffer
  293.  *    is used when reading the message text).
  294.  *
  295.  *    Parameters:   None
  296.  *
  297.  *    Returns:      0                   - Failure
  298.  *                  1                   - Success
  299.  *
  300.  * ---------------------------------------------------------------------- */
  301.  
  302. int DisplayMsgSubFld( void )
  303. {
  304.   UINT32  SubFldLen = JamRec.Hdr.SubfieldLen,
  305.           Len;
  306.  
  307.   printf( "Message number: %lu\n\n", JamRec.Hdr.MsgNum );
  308.  
  309.  
  310. /*
  311. **  Read the message header (and subfields)
  312. */
  313.  
  314.   if( !JAMmbFetchMsgHdr( &JamRec, JamRec.Hdr.MsgNum, 1 ))
  315.     {
  316.     printf( "Error reading message header, code: %d, errno: %d\n", JamRec.APImsg, JamRec.Errno );
  317.     return( 0 );
  318.     }
  319.  
  320.  
  321. /*
  322. **  If it wasn't possible to read all subfields into the buffer, only
  323. **  process those that fit into the buffer
  324. */
  325.  
  326.   if( SubFldLen > JamRec.WorkLen )
  327.     SubFldLen = JamRec.WorkLen;
  328.  
  329.  
  330. /*
  331. **  Display all the subfields
  332. */
  333.  
  334.   puts( " HiID LoID Name             Len Data\n"
  335.         " ---- ---- ----             --- ----" );
  336.  
  337.   for(  JamRec.SubFieldPtr = ( JAMSUBFIELD * ) JamRec.WorkBuf;
  338.  
  339.         JamRec.SubFieldPtr->DatLen + sizeof( JAMBINSUBFIELD ) <= SubFldLen;
  340.  
  341.         Len = JAMsysAlign( JamRec.SubFieldPtr->DatLen + sizeof( JAMBINSUBFIELD )),
  342.         SubFldLen -= Len,
  343.         JamRec.SubFieldPtr = JAMsysAddPtr( JamRec.SubFieldPtr, Len ))
  344.     {
  345.     printf( "%5u%5u %-14.14s%6lu \"%s\"\n",
  346.                         JamRec.SubFieldPtr->HiID, JamRec.SubFieldPtr->LoID,
  347.                         GetSubFldName( JamRec.SubFieldPtr ),
  348.                         JamRec.SubFieldPtr->DatLen,
  349.                         GetSubFldStr( JamRec.SubFieldPtr ));
  350.     }
  351.  
  352.   return( 1 );
  353. }
  354.  
  355.  
  356. /* ---------------------------------------------------------------------- *
  357.  *
  358.  *  DisplayMsgTxt
  359.  *
  360.  *    Displays the text of the current message. The message text is
  361.  *    first read. For message texts that doesn't fit into the work-
  362.  *    buffer, the text is read part by part
  363.  *
  364.  *    Parameters:   None
  365.  *
  366.  *    Returns:      0                   - Failure
  367.  *                  1                   - Success
  368.  *
  369.  * ---------------------------------------------------------------------- */
  370.  
  371. int DisplayMsgTxt( void )
  372. {
  373.   int       First = 1,          /* Flag if this is the first read */
  374.             Col = 0;
  375.   UINT32    Pos = 0;
  376.   UCHAR8  * p;
  377.  
  378.   printf( "Message number: %lu\n\n", JamRec.Hdr.MsgNum );
  379.  
  380.   while( 1 )
  381.     {
  382.  
  383. /*
  384. **  Get one part of the message
  385. */
  386.  
  387.     if( !JAMmbFetchMsgTxt( &JamRec, First ))
  388.       {
  389.       printf( "Error reading message text, code: %d, errno: %d\n", JamRec.APImsg, JamRec.Errno );
  390.       return( 0 );
  391.       }
  392.  
  393.     if( JamRec.APImsg == JAMAPIMSG_NOMORETEXT )
  394.       break;
  395.  
  396.     First = 0;
  397.  
  398.  
  399. /*
  400. **  Display the message text
  401. */
  402.  
  403.     for( p = ( UCHAR8 * ) JamRec.WorkBuf; Pos < JamRec.WorkPos; Pos++, p++ )
  404.       {
  405.       if( *p == '\r' )
  406.         {
  407.         puts( "<0d>" );
  408.         Col = 0;
  409.         continue;
  410.         }
  411.  
  412.       else if( *p < ' ' )
  413.         {
  414.         printf( "<%02x>", *p );
  415.         Col += 4;
  416.         }
  417.  
  418.       else
  419.         {
  420.         if( Col > 70 && *p == ' ' )
  421.           {
  422.           putchar( '\n' );
  423.           Col = 0;
  424.           }
  425.         else
  426.           {
  427.           putchar( *p );
  428.           Col++;
  429.           }
  430.         }
  431.       }
  432.     }
  433.  
  434.   puts( "" );
  435.  
  436.   return( 1 );
  437. }
  438.  
  439.  
  440. /* ---------------------------------------------------------------------- *
  441.  *
  442.  *  DisplayHdrInfo
  443.  *
  444.  *    Display the header information record, found first in the message
  445.  *    header file. Also calculate the total number of messages, and the
  446.  *    number of deleted messages
  447.  *
  448.  *    Parameters:   None
  449.  *
  450.  *    Returns:      0                   - Failure
  451.  *                  1                   - Success
  452.  *
  453.  * ---------------------------------------------------------------------- */
  454.  
  455. int DisplayHdrInfo( void )
  456. {
  457.   INT32   TotalMsgs;
  458.  
  459.   printf( "Header info\n\n" );
  460.  
  461.  
  462. /*
  463. **  Read the header information record
  464. */
  465.  
  466.   if( !JAMmbUpdateHeaderInfo( &JamRec, 0 ))
  467.     {
  468.     printf( "Error reading header info, code: %d, errno: %d\n", JamRec.APImsg, JamRec.Errno );
  469.     return( 0 );
  470.     }
  471.  
  472.  
  473. /*
  474. **  Calculate the total (active + deleted) number of messages
  475. */
  476.  
  477.   TotalMsgs = filelength( JamRec.IdxHandle ) / sizeof( JAMIDXREC );
  478.  
  479.  
  480. /*
  481. **  Display the information
  482. */
  483.  
  484.   printf( "Signature    : <%02x><%02x><%02x><%02x>\n",
  485.                                     JamRec.HdrInfo.Signature [0],
  486.                                     JamRec.HdrInfo.Signature [1],
  487.                                     JamRec.HdrInfo.Signature [2],
  488.                                     JamRec.HdrInfo.Signature [3] );
  489.   printf( "DateCreated  : %s",      JamRec.HdrInfo.DateCreated ? DispTime( &JamRec.HdrInfo.DateCreated ) : "<null>\n" );
  490.   printf( "ModCounter   : %lu\n",   JamRec.HdrInfo.ModCounter );
  491.   printf( "ActiveMsgs   : %lu\n",   JamRec.HdrInfo.ActiveMsgs );
  492.   printf( "PasswordCRC  : %08lx\n", JamRec.HdrInfo.PasswordCRC );
  493.   printf( "BaseMsgNum   : %lu\n",   JamRec.HdrInfo.BaseMsgNum );
  494.   puts( "" );
  495.   printf( "TotalMsgs    : %lu\n",   TotalMsgs );
  496.   printf( "DeletedMsgs  : %lu\n",   TotalMsgs - JamRec.HdrInfo.ActiveMsgs );
  497.  
  498.   return( 1 );
  499. }
  500.  
  501.  
  502. /* ---------------------------------------------------------------------- *
  503.  *
  504.  *  AttrToStr
  505.  *
  506.  *    Convert the Attribute field to a ASCIIZ string containing all the
  507.  *    attribute names
  508.  *
  509.  *    Parameters:   UINT32 Attr   - The attributes to convert
  510.  *
  511.  *    Returns:      CHAR8 *       - Ptr to buffer with attribute names
  512.  *
  513.  * ---------------------------------------------------------------------- */
  514.  
  515. CHAR8 * AttrToStr( UINT32 Attr )
  516. {
  517.   static CHAR8    Buf [256];
  518.   CHAR8         * p = Buf;
  519.   int             i;
  520.  
  521.   Buf [0] = '\0';
  522.  
  523.   for( i = 0; i < 32; i++ )
  524.     {
  525.     if( Attr & 0x00000001L )
  526.       {
  527.       if( p != Buf )
  528.         {
  529.         *p++ = ',';
  530.         *p++ = ' ';
  531.         }
  532.       strcpy( p, AttrName [i] );
  533.       p = strchr( p, '\0' );
  534.       }
  535.  
  536.     Attr >>= 1;
  537.     }
  538.  
  539.   return( Buf );
  540. }
  541.  
  542.  
  543. /* ---------------------------------------------------------------------- *
  544.  *
  545.  *  GetSubFldName
  546.  *
  547.  *    Get the name of the specified subfield
  548.  *
  549.  *    Parameters:   JAMSUBFIELD * pSubFld   - Ptr to subfield
  550.  *
  551.  *    Returns:      CHAR8 *                 - Name of subfield
  552.  *
  553.  * ---------------------------------------------------------------------- */
  554.  
  555. CHAR8 * GetSubFldName( JAMSUBFIELD * pSubFld )
  556. {
  557.   int     i;
  558.  
  559.   for( i = 0; i < sizeof( SubFieldInfo ) / sizeof( SubFieldInfo [0] ); i++ )
  560.     {
  561.     if( pSubFld->LoID == SubFieldInfo [i].LoID &&
  562.         pSubFld->HiID == SubFieldInfo [i].HiID )
  563.       return( SubFieldInfo [i].pName );
  564.     }
  565.  
  566.   return( "Undefined" );
  567. }
  568.  
  569.  
  570. /* ---------------------------------------------------------------------- *
  571.  *
  572.  *  GetSubFldStr
  573.  *
  574.  *    Convert the subfield contents to a string that can be displayed
  575.  *
  576.  *    Parameters:   JAMSUBFIELD * pSubFld   - Ptr to subfield
  577.  *
  578.  *    Returns:      CHAR8 *                 - Ptr to buffer containing
  579.  *                                            subfield contents
  580.  *
  581.  * ---------------------------------------------------------------------- */
  582.  
  583. CHAR8 * GetSubFldStr( JAMSUBFIELD * pSubFld )
  584. {
  585.   static CHAR8    Buffer [256],
  586.                 * pBuf;
  587.   UINT32          i;
  588.   int             BufPos;
  589.  
  590.   for(  pBuf = Buffer, i = BufPos = 0;
  591.         i < pSubFld->DatLen && BufPos + 5 < sizeof( Buffer );
  592.         pBuf++, i++, BufPos++ )
  593.     {
  594.     if( pSubFld->Buffer [( int ) i] < ' ' )
  595.       {
  596.       sprintf( pBuf, "<%02x>", pSubFld->Buffer [( int ) i] );
  597.       BufPos += 3;
  598.       pBuf += 3;
  599.       }
  600.     else
  601.       *pBuf = pSubFld->Buffer [( int ) i];
  602.     }
  603.  
  604.   *pBuf = '\0';
  605.  
  606.   return( Buffer );
  607. }
  608.  
  609.  
  610. /* ---------------------------------------------------------------------- *
  611.  *
  612.  *  DispTime
  613.  *
  614.  *    Converts the specified time to a ASCII string
  615.  *
  616.  *    Parameters:   UINT32 * pt             - # of seconds since 1970
  617.  *
  618.  *    Returns:      CHAR8 *                 - Ptr to buffer containing
  619.  *                                            ASCII string
  620.  *
  621.  * ---------------------------------------------------------------------- */
  622.  
  623. CHAR8 * DispTime( UINT32 * pt )
  624. {
  625.   static CHAR8    MonthNames [12][4] = {"Jan","Feb","Mar","Apr","May","Jun",
  626.                                         "Jul","Aug","Sep","Oct","Nov","Dec"};
  627.   static CHAR8    Buffer [64];
  628.   struct JAMtm  * ptm;
  629.  
  630.   ptm = JAMsysLocalTime( pt );
  631.   sprintf( Buffer, "%s %d, %4d  %2d:%02d:%02d\n",
  632.           MonthNames [ptm->tm_mon], ptm->tm_mday, ptm->tm_year + 1900,
  633.           ptm->tm_hour, ptm->tm_min, ptm->tm_sec );
  634.  
  635.   return( Buffer );
  636. }
  637.  
  638.  
  639. #if !defined(__MSDOS__)
  640.  
  641. /* ---------------------------------------------------------------------- *
  642.  *
  643.  *  filelength
  644.  *
  645.  * ---------------------------------------------------------------------- */
  646.  
  647. UINT32 filelength( int fh )
  648. {
  649.   UINT32    Pos,
  650.             Length;
  651.  
  652.   Pos = JAMsysSeek( NULL, fh, SEEK_CUR, 0L );
  653.   Length = JAMsysSeek( NULL, fh, SEEK_END, 0L );
  654.   JAMsysSeek( NULL, fh, SEEK_SET, Pos );
  655.  
  656.   return( Length );
  657. }
  658.  
  659. #endif
  660.  
  661.  
  662. /* end of file "jamutil.c" */
  663.